<template>
  <button
    :class="buttonClass"
    :disabled="disabled || loading"
    @click="handleClick"
  >
    <view v-if="loading" class="mr-2">
      <view class="animate-spin">
        <text class="i-carbon-loading"></text>
      </view>
    </view>
    <view v-if="$slots.prefix" class="mr-2">
      <slot name="prefix"></slot>
    </view>
    <view v-if="$slots.default" class="inline-flex items-center">
      <slot></slot>
    </view>
    <text v-else>{{ text }}</text>
    <view v-if="$slots.suffix" class="ml-2">
      <slot name="suffix"></slot>
    </view>
  </button>
</template>

<script setup lang="ts">
import { computed } from 'vue'

interface Props {
  // 按钮类型
  type?: 'primary' | 'secondary' | 'ghost'
  // 按钮尺寸
  size?: 'small' | 'medium' | 'large'
  // 按钮文本
  text?: string
  // 是否禁用
  disabled?: boolean
  // 是否加载中
  loading?: boolean
  // 是否块级按钮
  block?: boolean
  // 是否圆角
  round?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  type: 'primary',
  size: 'medium',
  text: '',
  disabled: false,
  loading: false,
  block: false,
  round: false,
})

const emit = defineEmits<{
  click: [event: Event]
}>()

const buttonClass = computed(() => {
  const baseClass = 'inline-flex items-center justify-center font-medium transition-all duration-200 focus:outline-none'

  const typeClasses = {
    primary: 'bg-novel-primary text-white border-novel-primary',
    secondary: 'bg-bg-light text-text-primary border-custom',
    ghost: 'bg-transparent text-novel-primary border-novel-primary',
  }

  const sizeClasses = {
    small: 'px-3 py-1.5 text-sm',
    medium: 'px-4 py-2 text-base',
    large: 'px-6 py-3 text-lg',
  }

  const shapeClasses = {
    default: 'rounded-custom',
    round: 'rounded-full',
  }

  const stateClasses = props.disabled || props.loading
    ? 'opacity-50 cursor-not-allowed'
    : 'hover:shadow-md active:scale-95'

  const blockClass = props.block ? 'w-full' : ''

  const borderClass = props.type !== 'primary' ? 'border' : ''

  return [
    baseClass,
    typeClasses[props.type],
    sizeClasses[props.size],
    shapeClasses[props.round ? 'round' : 'default'],
    stateClasses,
    blockClass,
    borderClass,
  ].filter(Boolean).join(' ')
})

const handleClick = (event: Event) => {
  if (!props.disabled && !props.loading) {
    emit('click', event)
  }
}
</script>

<style scoped>
.animate-spin {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>